// VBMcgi_raw.h

/////////////////////////////////////////////////////////////////////////////////////
//
// VBMcgi_raw.h
// www.VBMcgi.org - The Villas-Boas and Martins cgi library
// Version 3.0
// 
/////////////////////////////////////////////////////////////////////////////////////

#ifndef __VBMCGI__
#define __VBMCGI__

/////////////////////////////////////////////////////////////////////////////////////
//
// includes for VBMcgi
//
/////////////////////////////////////////////////////////////////////////////////////

// must be version 6.2 of VBLib
#include "VBLib/VBLib.h" 

// VBMcgi classes
#include "VBMcgi/VBMenuHtml.h"
#include "VBMcgi/VBPageCount.h"
#include "VBMcgi/VBTableMonth.h"
#include "VBMcgi/VBSessionServer.h"


// all entities in namespace br::com::sbVB::VBMcgi
namespace br {
namespace com {
namespace sbVB {
namespace VBMcgi {

/////////////////////////////////////////////////////////////////////////////////////
//
// Defines for string mensages
//
/////////////////////////////////////////////////////////////////////////////////////

// used when some file cannot be open or write
#define CANOTOPENFILE "Cannot process file "

// used when memory alloc fail
#define INTERNAL_ERROR "Internal VBMcgi Error (failed to alloc memory)"  

// used when no getenv(QUERY_STRING) return NULL
#define NO_QUERY_STRING	"someName=someValue"  

// define string to find when search for function in html code, like SSI
// signature of call
#define CALL_SIG "VBMCGI_CALL"

// define maximal value for data upload (through POST) in one chunck
// for now (2003-01-20) VBMcgi::formDecode only deals with one chunck
#define MAX_CONTENT_LENGTH 8*1024*1024 // 8MB

//#define addFunction(fun,obj) addFunctionHelper(#fun,fun,(void*)& obj)
#define addFunction(fun) addFunctionHelper(#fun,fun)
#define addFunctionObj(fun,obj) addFunctionHelper(#fun,fun,(void*)& obj)

/////////////////////////////////////////////////////////////////////////////////////
//
// defines for old compatibility
// these will be discontinued in future versions
//
/////////////////////////////////////////////////////////////////////////////////////
// #define urldecode formDecode
// #define vbmcgi VBMcgi
// #define htmlHeader httpHeader
// #define htmlCompleteHeader httpCompleteHeader


class VBMcgi; // early class definition

// function pointer type definition of functions that can 
// be called by VBMCGI_CALL, and addFunction method
typedef void (*fpType)(VBMcgi &obj, void *p);


// main VBMcgi class
class VBLIB_DLL_API VBMcgi
{
	////////////////////////////////////////////////////////////////////////////////
	// classes inside VBMcgi
	////////////////////////////////////////////////////////////////////////////////

	class funcNode 
	{
	public:
		br::com::sbVB::VBLib::VBString m_funName;
		fpType m_funPtr; 
		void *m_pToUserClass;

		funcNode(const char *funName = "", fpType funPtr=0, void *pToUserClass=0) 
		{
			m_funName = funName;
			m_funPtr = funPtr;
			m_pToUserClass = pToUserClass;
		}
	};

	class VBMcgi_xchgNode 
	{
	public:
		br::com::sbVB::VBLib::VBString m_find, m_replace;

		VBMcgi_xchgNode(const char *find="", const char *replace="") {
			m_find = find;
			m_replace = replace;
		}

		bool operator==(const VBMcgi_xchgNode &obj) { // ret = (this==a);
			return m_find == obj.m_find;
		}

	};

	enum HttpMethod 
	{
		GET,
		POST,
		UNDEFINED
	};

	char m_tok; // for getHtmlParameter
	std::ostream *m_pcout;

	////////////////////////////////////////////////////////////////////////////////
	// attributes for cookie
	////////////////////////////////////////////////////////////////////////////////

	br::com::sbVB::VBLib::VBString m_cexpires, m_current_time, m_cpath, m_cdomain, m_cnamevalue;
	bool m_csecure;

	// list of pairs of strings (search string and replace string)
	br::com::sbVB::VBLib::VBList<VBMcgi_xchgNode> m_xchgList;

	// list form fields and contents in the form decode, for getVarContent (GVC)
	// in version 1.x, it was done m_xchgList and m_xchgListGVC were the same variable
	br::com::sbVB::VBLib::VBList<VBMcgi_xchgNode> m_xchgListGVC;

	// list of functions to be replaced in VBMCGI_CALL(userFunction)
	br::com::sbVB::VBLib::VBList<funcNode> m_funcList;

	// defined inside the VBMcgi object, but used as a global variable due to the "static"
	static bool m_static_haveHeader;

	// check if functionName exist in linked list of function
	// if true, run relative function
	bool runFunction (const char *functionName);

	// path to the directory where to save uploaded files
	br::com::sbVB::VBLib::VBString m_uploadDir;

	// html parameners
	// parameters that one pass from html directly to the user function with VBMCGI_CALL
	// example: VBMCGI_CALL(userFun,1,2,3) => htmlParameters are 1,2,3
	br::com::sbVB::VBLib::VBString m_htmlParameters;
	unsigned m_numberOfParameters;

	// http header in a special situation
	void httpHeader(const char *headerType,const char *pageTitle);

public:

	// the public member m_cout is to be used as cout in VBMCGI_CALL functions
	// this should be ostream & m_cout, but the compiler won't accept it :(
	// because there is no operator= defined for ostream_withassign
	// ostream * m_cout;

	// constructors
	VBMcgi(); // default constructor
	VBMcgi(const VBMcgi & obj); // copy constructor
	void setOstream(std::ostream * pcout);
	void operator=(const VBMcgi & obj);

	// decode a given queryString
	void decodeQueryStringVBString(br::com::sbVB::VBLib::VBString & queryStringStr,
		bool copyToGetVarContents=true);
	void decodeQueryString(const char * queryString,bool copyToGetVarContents=true);


	// set name/value pairs in cookie, add separator betwen pairs 
	void setCookieNameValue(const char *cookieName, const char *cookieValue);

	// set expires value to cookie, can be: now, end of session
	// or in any future time, like: x minutes or y hours or z years
	bool setCookieExpires(const char *period, int value=0);

	// set all others (optional) field in cookie structure
	// like: path, domain and secure
	void setCookieField(const char *cookieField, const char *value);
	
	// send cookie structure to browser.  name and value must be set
	// after this, reset name and value variables, but leave anyone else
	void sendCookie();

	// return cookie value from HTTP_COOKIE variable, if existe, else null
	br::com::sbVB::VBLib::VBString getCookieValue(const char *cookieName);

	// return cookie value from string in HTTP_COOKIE format, if existe, else null
	br::com::sbVB::VBLib::VBString getCookieValueFromHttpCookie
		(const char *http_cookie,const char *cookieName);

	// return true if cookie named cookieName exists
	bool existCookie (const char *cookieName);
	
	// add pair variable/content from source code 
	void addBySource(const char* find, const char* replace);
	void addBySource(const char* find, char replace);
	void addBySource(const char* find, unsigned replace);
	void addBySource(const char* find, int replace);
	void addBySource(const char* find, double replace);
	void addBySource(const char* find, float replace);

	// add pair variable/content from external file
	bool addByFile(const char* filein);

	// remove pair variable/content from source code 
	void removeBySource(const char* find);
	
	// add pair variable/content from external file BUT
	// using special structure to improve more uses
	bool addBySpecialFile(const char* filein);

	// return the data content variable partner with name passed
	br::com::sbVB::VBLib::VBString getVarContent(const char* find);

	// check if some var name and var content match
	// this method is used in special situations
	// the usage with variable number of parameters is rare
	bool getVarContent(const char *find,const  char *replace, ...);

	// easy-to-use method to get check-box
	bool getCheckBox(const char *find,const  char *replace);

	// put pairs of function name and pointers to functions
	// in a linked list to future use from runFunction
	bool addFunctionHelper (const char *functionName, fpType ptr, void *p=0);

	// the main method to output data implementing 
	// string change feature and call function feature
	void out(const char* filein); 
	
	// get and set m_uploadDir
	br::com::sbVB::VBLib::VBString getUploadDir() { return m_uploadDir; }
	void setUploadDir(br::com::sbVB::VBLib::VBString dir) { m_uploadDir=dir; } // MUST have a trailing '/' (unix) or '\' (win)
		
	// get html parameters
	br::com::sbVB::VBLib::VBString getHtmlParameterString() { return m_htmlParameters; }
	br::com::sbVB::VBLib::VBString getHtmlParameter(unsigned i); 
	unsigned getHtmlParameterNumber() {return m_numberOfParameters; }
	
	// http headers
	void httpHeader(const char *headerType="text/html");
	void httpCompleteHeader(const char *headerType="text/html");

	// send to stdout error msg
	void htmlError (const char* errorMsg);

	// decode variable from forms
	// new name of urldecode
	int formDecode(bool copyToGetVarContents = false);

	// redirects browser to szUrl 
	void redirect(const char *szUrl);

	// upload ONE file
	// bool upload (const char *fileName);
	br::com::sbVB::VBLib::VBString systemTime();
	br::com::sbVB::VBLib::VBString systemDatePortuguese();

	bool insertLine (VBMcgi &obj, const char *fileName, const char *reservedString, 
			const char *inputString, int insMode);

	bool fileToggle(VBMcgi &obj, const char *szFile);

	char getTok() const;
	void setTok(char tok);

}; 

// START - new code block by Mauricio de Alencar 2002-08-06
/*class VBHtmlCall {
public:		  
		  virtual void getDataFromString(const char *parameters)=0;
};*/
// END - new code block by Mauricio de Alencar 2002-08-06


/////////////////////////////////////////////////////////////////////////////////////
//
// global functions
//
/////////////////////////////////////////////////////////////////////////////////////

VBLIB_DLL_API bool VBMcgi_isBadString(br::com::sbVB::VBLib::VBString link);

// VBMcgi's callBacks for call function feature
VBLIB_DLL_API void file(VBMcgi & cgi, void *p);
VBLIB_DLL_API void SSI(VBMcgi & cgi, void *p);

// outputs buildID information
VBLIB_DLL_API	void buildID();

}}}} // close namespace ::br::com::sbVB::VBMcgi



#endif // __VBMCGI__

